home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char SccsId[]= "@(#)pixreps.c V1.11 3/13/95";
- #endif
- /*
- | file name - pixreps.c
- |===================================================================
- |
- | This program demonstrates the use of pixreps. It allows the user
- | to create a pixrep whose red, green and blue components are taken
- | from any combination of three other pixreps.
- |
- | The image used in this example program is found in the
- | <dataviews>/lib/images directory.
- |
- | The programs ends if the user selects the <q|Q> key or the
- | right mouse button.
- |
- |===================================================================
- */
- #include <windows.h>
-
- /*
- * DV-Tools header files
- */
- #include "std.h" /* <stdio.h> etc., scalar & macro definitions */
- #include "dvstd.h" /* public types & constants */
- #include "dvtools.h" /* constants used by T routines */
- #include "dvGR.h" /* constants used by window mgt & GR routines */
- #include "VOstd.h" /* constants used by VO & VOob routines */
- #include "Tfundecl.h" /* T routines (screens, drawports & views) */
- #include "VOfundecl.h" /* VO routines (objects) */
- #include "VUerfundecl.h" /* VUer routines (event handling routines) */
- #include "VUpixrep.h" /* Contains the pixscan macros */
- #include "VGfundecl.h" /* VG routines (get info from dgp & vdp) */
- #include "VUfundecl.h" /* VU routines (Utility) */
- #include "GRfundecl.h" /* GR routines (interface to display device) */
-
- /* Constants */
- #define DVPATH (char *)NULL
- #define DISPFORMS_STB (char *)NULL
- #define DVDEVICE (char *)NULL
- #define DVCOLORTABLE (char *)NULL
- #define VIEW_NAME "pixreps.v"
- #define SCREEN_VIEWPORT (RECTANGLE *)NULL
- #define DRAWING_VIEWPORT (RECTANGLE *)NULL
-
-
- /* height and width of the pixreps */
- #define PIXWIDTH 128
- #define PIXHEIGHT 128
-
- PIXREP pixrep[4]; /* initial pixreps */
- PIXREP mergedpixrep; /* merged pixreps */
-
- COLOR_TABLE GreyClut; /* Greyscale color table */
- COLOR_TABLE *DeviceClut; /* current device clut */
-
- /* which pixreps provide which component */
- UBYTE RedBuf = 1;
- UBYTE GreenBuf = 2;
- UBYTE BlueBuf = 3;
- UBYTE LastRed, LastGreen, LastBlue;
-
- DRAWPORT drawport;
- OBJECT drawing, icon[5];
-
- /* Functions defined in pixreps.c */
- LOCAL void CreatePixrep1 V_P_((void));
- LOCAL void CreatePixrep2 V_P_((void));
- LOCAL void CreatePixrep3 V_P_((void));
- LOCAL void CreateMergedPixrep V_P_((void));
- LOCAL void MergePixreps V_P_((void));
- LOCAL ADDRESS RebindVdps V_P_((OBJECT data_obj, ADDRESS vdp,
- ADDRESS argblock));
-
- /***************** End Function Declarations *************/
- int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpCmdLine, int nCmdShow )
- {
- /*
- * program arguments
- * argv[1] - display device name (default is to use DVDEVICE)
- */
-
- /* Define & initialize device name and view filename */
- char *device_name = DVDEVICE; /* default device name */
- char *view_name = VIEW_NAME; /* default view name */
-
- OBJECT screen, location;
- VIEW view;
- OBJECT pixmap;
- int Quit = NO, i;
-
- int argc;
- char **argv;
-
-
- make_argv(&argc,&argv,GetCommandLine());
- /*--------------------
- * Initialization
- *
- * TInit: perform the initialization of DV-Tools
- * TInit reads your configuration file and any
- * environment variables or logical names set.
- */
- TInit (DVPATH, DISPFORMS_STB);
-
- /*
- * TscOpenSet: open a device as a screen object using
- * specified attributes
- * TscErase: erase the entire screen in the default
- * background color
- *
- * Set exposure block to YES to insure the window
- * is ready for drawing when TdpDraw is called.
- */
- if (argc > 1)
- device_name = argv[1];
- screen = TscOpenSet (device_name, DVCOLORTABLE,
- V_WINDOW_WIDTH, 840,
- V_WINDOW_HEIGHT, 644,
- V_X_EXPOSURE_BLOCK, YES,
- V_ACTIVE_CURSOR, V_END_OF_LIST);
- if (!screen)
- {
- printf ("Must specify device on command line or");
- printf (" in DataViews configuration file.\n");
- S_EXIT (EXIT_ERR);
- }
- TscErase (screen);
-
- /* Set the window events that we need to know about */
- VOscWinEventMask ((ULONG) V_KEYPRESS | V_BUTTONPRESS | V_MOTIONNOTIFY |
- V_RESIZE | V_EXPOSE,
- (ULONG) 0);
- view = TviLoad (view_name);
- drawport = TdpCreateStretch (screen, view, SCREEN_VIEWPORT,
- DRAWING_VIEWPORT);
-
- /*
- * Traverse all variable descriptors in the drawing object
- * call the function RebindVdps for each variable descriptor.
- */
- drawing = TviGetDrawing (view);
- TobForEachVdp (drawing, (TOBFOREACHVDPFUNPTR)RebindVdps, (ADDRESS) NULL);
-
- icon[1] = VOicReference (TdrGetNamedObject (drawing, "icon1"));
- VOdrObDelete (drawing, icon[1]);
- icon[2] = VOicReference (TdrGetNamedObject (drawing, "icon2"));
- VOdrObDelete (drawing, icon[2]);
- icon[3] = VOicReference (TdrGetNamedObject (drawing, "icon3"));
- VOdrObDelete (drawing, icon[3]);
- icon[4] = VOicReference (TdrGetNamedObject (drawing, "mergedicon"));
- VOdrObDelete (drawing, icon[4]);
-
- /* =========================================================== */
- /* Create pixreps, create pixmap objects from pixreps, and */
- /* replace icon's initial pixmaps with the new pixmaps. */
- /* =========================================================== */
-
- /* create a greyscale color table for use by pixreps. */
- for (i = 0; i < 256; i++)
- {
- GreyClut.ct[i].red = i;
- GreyClut.ct[i].green = i;
- GreyClut.ct[i].blue = i;
- }
- GreyClut.ctsize = 256;
-
- /* find actual colors displayed on the screen */
- GRg_real_color_tab (&DeviceClut);
-
- CreatePixrep1 ();
- CreatePixrep2 ();
- CreatePixrep3 ();
-
- /* ========================= */
- /* start displaying the view */
- /* ========================= */
- TdpDraw (drawport);
-
- CreateMergedPixrep ();
-
- pixmap = VOpmCreate ((char *)NULL, (ADDRESS) & pixrep[1]);
- /* Dither pixmap so it displays better given the limited number
- | of greys in the default color table.
- */
- VOpmNewColorTable (pixmap, DeviceClut, YES);
- VOicSet (icon[1], V_IC_PIXMAP, pixmap,
- V_IC_WIDTH, PIXWIDTH,
- V_IC_HEIGHT, PIXHEIGHT,
- V_IC_PIXMAP_XFORM, NULL,
- V_IC_ATTR_ARGEND);
-
- pixmap = VOpmCreate ((char *)NULL, (ADDRESS) & pixrep[2]);
- VOpmNewColorTable (pixmap, DeviceClut, YES);
- VOicSet (icon[2], V_IC_PIXMAP, pixmap,
- V_IC_WIDTH, PIXWIDTH,
- V_IC_HEIGHT, PIXHEIGHT,
- V_IC_PIXMAP_XFORM, NULL,
- V_IC_ATTR_ARGEND);
-
- pixmap = VOpmCreate ((char *)NULL, (ADDRESS) & pixrep[3]);
- VOpmNewColorTable (pixmap, DeviceClut, YES);
- VOicSet (icon[3], V_IC_PIXMAP, pixmap,
- V_IC_WIDTH, PIXWIDTH,
- V_IC_HEIGHT, PIXHEIGHT,
- V_IC_PIXMAP_XFORM, NULL,
- V_IC_ATTR_ARGEND);
-
- for (i = 1; i < 4; i++)
- TdpDrawObject (drawport, icon[i]);
-
- FOREVER
- {
-
- /* Get the latest event */
- location = VOloWinEventPoll (V_WAIT);
- switch (VOloType (location))
- {
-
- case V_EXPOSE:
- TscRedraw (screen, (RECTANGLE *) NULL);
- for (i = 1; i <= 4; i++)
- TdpRedrawObject (drawport, icon[i]);
- break;
-
- case V_RESIZE:
- TscReset (screen);
- break;
-
- case V_KEYPRESS:
- switch (VOloKeySym (location))
- {
- case 'q':
- case 'Q':
- Quit = YES;
- break;
-
- default:
- break;
- }
- break;
-
- case V_BUTTONPRESS:
- case V_MOTIONNOTIFY:
- /*
- * Call the event handler so input objects respond to
- * user interactions.
- */
- VUerHandleLocEvent (location);
-
- /* if the color values have changed since last time,
- * modify the merged pixrep.
- */
- if (LastRed != RedBuf || LastBlue != BlueBuf ||
- LastGreen != GreenBuf)
- MergePixreps ();
-
- /*
- * Update the dynamic parts of the current drawport by
- * redrawing the dynamic elements that have changed.
- */
- TdpDrawNext (drawport);
- break;
-
- default:
- break;
- }
- if (Quit == YES)
- break;
- }
-
- /*
- * When finished, destroy the current drawport and view
- * close the graphics device and terminate DV-Tools.
- */
- TscErase (screen);
- TdpDestroy (drawport);
- TviDestroy (view);
- TscCloseCurrentScreen ();
- TTerminate ();
- return (EXIT_OK);
- }
-
- /*
- * CreatePixrep1()
- * This illustrates creating a pixrep "from scratch", such as might be
- * done if you want to convert data from an external source into
- * a pixrep.
- * Pixrep 1 starts out white on the left edge and fades to
- * black towards the right edge.
- */
- LOCAL void CreatePixrep1 ()
- {
- #ifndef USE_PIXSCAN_MACROS
- int i;
- #else
- PIXSCAN pixscan;
- PIXPTR pixptr;
- ULONG pixval;
- #endif
-
- int x, y;
- UBYTE *pixel_data;
-
- /*
- * Initialize a pixrep. In this program there is no real reason to prefer
- * one layout over another, but for illustration we'll create one
- * with a specific format:
- * 8 bits per pixel of indirect color, the bottom row of the pixrep
- * will be row 0 (i.e. comes first in the data array) and rows
- * are contiguous in memory (no padding between rows).
- */
- pixrep[1].height = PIXHEIGHT;
- pixrep[1].width = PIXWIDTH;
- pixrep[1].origin_at_ll = YES; /* row[0] is bottom row */
- pixrep[1].row_alignment = 8; /* rows contiguous */
- pixrep[1].pack_unit = 8; /* only matters if bits/pixel < 8 */
- pixrep[1].pack_msf_in_byte = NO; /* only matters if bits/pixel < 8 */
- pixrep[1].pack_msf_in_unit = YES; /* only matters if bits/pixel < 8 */
- pixrep[1].depth = 8;
- pixrep[1].bits_per_pixel = 8;
- pixrep[1].pclut = (COLOR_TABLE *) S_ALLOC ((LONG) sizeof (COLOR_TABLE));
- *pixrep[1].pclut = GreyClut;
- pixrep[1].color_used = NULL; /* all colors will be used anyway */
- pixrep[1].pixels_length = PIXHEIGHT * VUpxBytesPerRow (&pixrep[1]);
- pixel_data = (UBYTE *) S_ALLOC ((LONG) pixrep[1].pixels_length);
- pixrep[1].pixels = pixel_data;
-
- #ifndef USE_PIXSCAN_MACROS
-
- /*
- * There are two ways to initialize the data. One way is to modify
- * the pixel data directly. (The data may also come from some
- * other source (such as an X XImage structure) and be used without
- * modification by setting the appropriate pixrep fields.)
- */
- i = 0;
- for (y = 0; y < PIXHEIGHT; y++)
- for (x = 0; x < PIXWIDTH; x++)
- pixel_data[i++] = 255 - (2 * x);
-
- #else
-
- /*
- * Or the data can be modified using the pixscan macros
- * The following is an example of initializing the data using the
- * pixscan macros.
- */
- VUpxScanInit (&pixrep[1], &pixscan, &pixptr, YES);
-
- for (y = 0; y < PIXHEIGHT; y++)
- for (x = 0; x < PIXWIDTH; x++)
- {
- pixval = 255 - (2 * x);
- PXSCANWRITE (pixrep[1], pixscan, pixptr, pixval);
- }
- #endif
- }
-
- /*
- * CreatePixrep2()
- * This illustrates creating a pixrep from a pixmap object.
- * It also shows how some of the pixrep utilities work as well
- * as how to use some of the pixscan macros.
- * Pixrep 2 is part of a greyscale version of rose.gif.
- */
- LOCAL void CreatePixrep2 ()
- {
- OBJECT pixmap;
- PIXREP *pixrepp;
- PIXREP tpixrep;
- RECTANGLE rect;
- PIXSCAN pixscan1, pixscan2;
- PIXPTR pixptr1, pixptr2;
- ULONG pixval;
- int i;
-
-
- pixmap = VOpmCreate ("rose.gif", (ADDRESS)NULL);
-
- if (!pixmap) /* failed, create a boring pixrep. */
- VUpxRotate (&pixrep[2], &pixrep[1], 180);
- else
- {
- VOpmGet (pixmap, V_PM_PIXREP_DATA, &pixrepp, V_PM_ATTR_ARGEND);
-
- /* clip out a 128x128 square from the pixrep (makes a COPY!) */
- rect.ll.x = 60;
- rect.ll.y = 50;
- rect.ur.x = rect.ll.x + PIXWIDTH - 1;
- rect.ur.y = rect.ll.y + PIXHEIGHT - 1;
- VUpxClip (&tpixrep, pixrepp, &rect);
-
- /* convert to greyscale (another copy) */
- VUpxNewColorTable (&pixrep[2], &tpixrep, &GreyClut, NO);
-
- /*
- * The rose is a bit dark, so brighten it a bit by increasing
- * each pixel's intensity by a few levels.
- * Create two pixscans, one to read a pixel from the pixrep
- * and one to write it back.
- */
- VUpxScanInit (&pixrep[2], &pixscan1, &pixptr1, YES);
- VUpxScanInit (&pixrep[2], &pixscan2, &pixptr2, YES);
- for (i = pixrep[2].width * pixrep[2].height; i > 0; i--)
- {
- PXSCANREAD (pixval, pixrep[2], pixscan1, pixptr1);
- pixval = S_MIN (pixval + 50, 255);
- PXSCANWRITE (pixrep[2], pixscan2, pixptr2, pixval);
- }
-
- /* cleanup */
- VOpmDereference (pixmap);
- VUpxFree (&tpixrep);
- }
-
- }
-
- /*
- * CreatePixrep3()
- * This illustrates another pixrep utility.
- * Pixrep 3 is simply a rotated version of pixrep 1.
- */
- LOCAL void CreatePixrep3 ()
- {
- VUpxRotate (&pixrep[3], &pixrep[1], 90);
- }
-
- /*
- * CreateMergedPixrep()
- * Create the pixrep that will hold the merged color information.
- */
- LOCAL void CreateMergedPixrep ()
- {
-
- /* Initialize the pixrep structure. The only things we care about
- * are the height, width and that it have 24 bits of direct color
- * information.
- */
- VUpxDefault (&mergedpixrep, PIXHEIGHT, PIXWIDTH, (COLOR_TABLE *) NULL,
- (ULONG) 0xFF, (ULONG) 0xFF00, (ULONG) 0xFF0000);
- mergedpixrep.pixels = (UBYTE *) S_ALLOC ((LONG) mergedpixrep.pixels_length);
-
- /* merge the initial pixreps together and put result in mergedpixrep */
- MergePixreps ();
- }
-
- /*
- * MergePixreps()
- * The color information for the merged pixrep comes from various
- * combinations of the three initial pixreps. This function merges
- * the chosen combination together and displays the result.
- */
- LOCAL void MergePixreps ()
- {
- OBJECT pixmap;
- PIXREP pixrepdraw;
-
- /* Erase existing icon while we're working */
- TdpEraseObject (drawport, icon[4]);
-
- /*
- * Combine the color components together. Modifies mergedpixrep, does
- * not create copy.
- *
- * Each pixrep contributes its red, green, or blue component to the
- * result. Since all three pixreps have a greyscale color table, each
- * color value in this table has equal components of red, green and
- * blue. This means that any of the three pixreps can be used for any
- * component.
- *
- * Suppose you wanted a pixrep's pixel values to be interpreted as the
- * green component for a new pixrep, but its color table consisted only of
- * levels of red. Simply change its "pclut" field (temporarily at least)
- * to point to a color table consisting of levels of green and continue
- * as below.
- */
-
- VUpxChannelMerge (&mergedpixrep, &pixrep[RedBuf], &pixrep[GreenBuf],
- &pixrep[BlueBuf]);
-
- /*
- * The result uses 24 bits of direct color. To get it to display nicely
- * on the current device, we create a copy of the pixrep that uses
- * the current device color table.
- * Dither the resulting pixrep so it looks better.
- */
- VUpxNewColorTable (&pixrepdraw, &mergedpixrep, DeviceClut, YES);
-
- /*
- * Turn pixrep into pixmap object and replace merged icon's current
- * pixmap with the new one.
- */
- pixmap = VOpmCreate ((char *)NULL, (ADDRESS) & pixrepdraw);
- VOicSet (icon[4], V_IC_PIXMAP, pixmap,
- V_IC_WIDTH, PIXWIDTH,
- V_IC_HEIGHT, PIXHEIGHT,
- V_IC_PIXMAP_XFORM, NULL,
- V_IC_ATTR_ARGEND);
-
- /* refresh the screen image of icon */
- TdpDrawObject (drawport, icon[4]);
-
- VUpxFree (&pixrepdraw);
-
- /* remember the colors just chosen */
- LastRed = RedBuf;
- LastGreen = GreenBuf;
- LastBlue = BlueBuf;
-
- }
-
- /*
- *-------------
- * RebindVdps -- modify the variable descriptor to use
- * our own program variable as the memory buffer.
- * The variable descriptor which had previously
- * pointed to a data source variable for the data
- * will now look at our program variable for the
- * data information.
- */
- /*ARGSUSED*/
- LOCAL ADDRESS
- RebindVdps (data_obj, vdp, argblock)
- OBJECT data_obj;
- ADDRESS vdp;
- ADDRESS argblock;
- {
- char *name; /* variable descriptor name */
-
- /*
- * VGvdvarname: Gets a pointer to the variable name
- *
- * The name of the variable descriptor is used to
- * determine which buffer to rebind to. If the
- * variable does not have a name then return.
- */
- name = VGvdvarname (vdp);
- if (!name)
- return V_CONTINUE_TRAVERSAL;
-
- /*
- * TvdPutBuffer: Sets a new variable descriptor buffer
- *
- * Rebind variable descriptor pointer to internal program
- * variable. Program variable will be updated for
- * dynamic objects.
- */
- if (strcmp (name, "red") == 0)
- TvdPutBuffer (vdp, (ADDRESS) & RedBuf);
- else if (strcmp (name, "green") == 0)
- TvdPutBuffer (vdp, (ADDRESS) & GreenBuf);
- else if (strcmp (name, "blue") == 0)
- TvdPutBuffer (vdp, (ADDRESS) & BlueBuf);
-
- return V_CONTINUE_TRAVERSAL;
- }
-